App.require(function () {
    var app = App.getCurrent();

    app.defineComponent("str-icon", {
        getDomObj: function () {
            this.attachDom("svg", "svg")
                .attachDom("i", "i")
                .attachEvent("i", "focus", this.focusHandler, false)
                .attachEvent("i", "blur", this.blurHandler, false)
                .attachEvent("i", "click", this.clickHandler, false);
        },
        _keyDownHandler: function (ev) {
            if (ev.key === "Enter") {
                this.clickHandler(ev);
            }
            if (ev.key === " ") {
                ev.preventDefault();
                this.clickHandler(ev);
            }
        },
        focusHandler: function (ev) {
            this.dispatchCustomEvent("iconfocus", { event: ev, component: this, target: ev.currentTarget });
            window.addEventListener("keydown", this.keyDownHandler, false);
        },
        blurHandler: function (ev) {
            this.dispatchCustomEvent("iconblur", { event: ev, component: this, target: ev.currentTarget });
            window.removeEventListener("keydown", this.keyDownHandler, false);
        },
        clickHandler: function (ev) {
            if (!this.property.disabled) {
                this.dispatchCustomEvent("iconclick", { event: ev, component: this, target: ev.currentTarget });
            }
        },
        render: function (next) {
            this.computeData();
            if (location.protocol == "file:") return next(this.renderHTML(App.staticHtml.strIconCom));
            this.fetch("index.html", function (text) {
                return next(this.renderHTML(text));
            })
        },
        changeIcon: function (icon, feeback) {
            if (icon === this.property.icon) {
                if (typeof feeback === "function") feeback();
                return;
            }
            this.property.icon = icon;
            this.loadIcon(icon, feeback);
        },
        loadIcon: function (icon, feeback) {
            if (location.protocol == "file:") {
                if (App.staticHtml.svg[icon]) {
                    this.changeIconText(App.staticHtml.svg[icon], icon, feeback);
                }
            }
            else {
                this.fetch("../../img/svg/" + icon + ".svg", function (text) {
                    this.changeIconText(text, icon, feeback);
                });
            }
        },
        changeIconText: function (text, icon, feeback) {
            var svgObj = this.getSvgObj(text);
            this.data.viewBox = svgObj.viewBox;
            this.data.path = svgObj.path;

            var svg = this.domList.svg;
            svg.setAttribute("viewBox", svgObj.viewBox);
            var children = svg.children;
            for (var i = children.length - 1; i >= 0; i--) {
                svg.removeChild(children[i]);
            }
            svg.classList.remove("str-icon-loading");

            var newDiv = document.createElement("div");
            newDiv.innerHTML = "<svg>" + svgObj.path + "</svg>";

            var children = newDiv.firstElementChild.children;
            for (var i = children.length - 1; i >= 0; i--) {
                svg.insertBefore(children[i], null);
            }

            if (typeof feeback === "function") {
                feeback(icon);
            }
        },
        init: function () {
            var that = this;
            this.loadIcon(this.property.icon, function (icon) {
                that.dispatchCustomEvent("iconload", { icon: icon, component: this });
            });
            this.keyDownHandler = this._keyDownHandler.bind(this);
        },
        computeData: function () {
            var property = this.property;
            property.disabled = typeof property.disabled === "undefined" ? "" : "disabled";
            if (!property.disabled && typeof property.nofocus === "undefined") {
                property.tabindex = property.tabindex || this.uid;
            }
            property.width = property.width || 24;
            property.height = property.height || property.width;
            property.name = property.name || "";
            property.color = property.color || "currentColor";
            property.class = property.class || "";
            var computedClass = property.disabled ? "str-icon-disabled" : "";
            if (property.disabled) property.class = property.class ? (property.class + " " + computedClass) : computedClass;
            this.data.propertystr = this.createPropertyStr({
                icon: property.icon, name: property.name, class: property.class
            });
        },
        getSvgObj: function (str) {
            var startSvg = str.indexOf("<svg"),
                startPath = str.indexOf("<path"),
                endSvg = str.indexOf("</svg");

            var svgHeader = str.slice(startSvg, startPath);
            var svgPath = str.slice(startPath, endSvg);
            var viewBox = /viewBox="(.*?)"/.exec(svgHeader)[1];
            return {
                path: svgPath,
                viewBox: viewBox
            };
        },
        set disabled(value) {
            if (value == this.property.disabled) return;
            if (value) {
                this.property.disabled = "disabled";
                this.domList.i.tabindex = this.index;
                this.domList.i.classList.add("str-icon-disabled");
            }
            else {
                this.property.disabled = "";
                this.domList.i.removeAttribute("tabindex");
                this.domList.i.classList.remove("str-icon-disabled");
            }
        },
        set icon(value) {
            if (this.property.icon === value) return;
            if (value) {
                this.property.icon = value;
                this.domList.i.setAttribute("icon", value);
                this.loadIcon(value);
            }
        },
        get icon() {
            return this.property.icon;
        },
        get name() {
            return this.property.name;
        },
        set width(value) {
            this.property.width = value;
            this.domList.svg.setAttribute("width", value);
        },
        get width() {
            return this.property.width;
        },
        set height(value) {
            this.property.height = value;
            this.domList.svg.setAttribute("height", value);
        },
        get height() {
            return this.property.height;
        },
        set color(value) {
            this.property.color = value;
            this.domList.svg.setAttribute("color", value);
        },
        get color() {
            return this.property.color;
        },
        get className() {
            return this.property.class;
        },
        set className(value) {
            if (this.property.class == value) return;
            this.domList.i.className = value;
            this.property.class = value;
        }
    });
});